package com.marion.mzuul.service;

import com.marion.mzuul.entity.mongo.UserLocationMG;
import com.marion.mzuul.repo.mongo.UserLocationRepository;
import com.marion.mzuul.vo.NearbyUser;
import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCollection;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class UserLocationService {

    @Autowired
    private UserLocationRepository userLocationRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 上传定位信息
     */
    public void gps(long uid, int gender, String address, double lon, double lat) {
        userLocationRepository.findByUid(uid).ifPresentOrElse(v -> {
            v.setGender(gender);
            v.setAddress(address);
            v.setLoc(Arrays.asList(lon, lat));
            userLocationRepository.save(v);
        }, () -> {
            UserLocationMG build = UserLocationMG.builder()
                    .uid(uid)
                    .gender(gender)
                    .address(address)
                    .loc(Arrays.asList(lon, lat))
                    .build();
            userLocationRepository.save(build);
        });
    }

    /**
     * 查询附近的人
     *
     * @param distance 2000000 = 2000m
     */
    public List<NearbyUser> nearby(long uid, long distance, int start, int count) {

        /**
         * 查询当前用户坐标
         */
        Optional<UserLocationMG> userLoc = userLocationRepository.findByUid(uid);
        if (userLoc.isEmpty()) {
            return new ArrayList<>();
        }

        UserLocationMG userLocationMG = userLoc.get();

        MongoCollection<org.bson.Document> collection = mongoTemplate.getCollection("user_location");

        //首先创建一个集合，泛型是BasicDBObject
        List<BasicDBObject> basicDBObjectList = new ArrayList<>();
        //创建一个BasicDBObject对象，然后拼接数据，它也是key-value类型的，对应拼接就行
        BasicDBObject basicDBObject = new BasicDBObject("$geoNear",
                new BasicDBObject("near", userLocationMG.getLoc()).//当前用户坐标
                        append("spherical", true).//计算球面距离
                        append("distanceMultiplier", 6378137).//地球半径,单位是米,那么的除的记录也是米
                        append("maxDistance", (double) distance / 6378137).//过滤条件2000米内，需要弧度，这里计算平局距离要加double，否则会查询全部数据
                        append("distanceField", "distance"));//距离字段别名
        //然后将这个对象add到集合中
        basicDBObjectList.add(basicDBObject);
        //然后用上面获取的collection对象中的aggregate方法，参数就是这个集合
        AggregateIterable<Document> inventory = collection.aggregate(basicDBObjectList);

        List<NearbyUser> ret = new ArrayList<>();
        for (Document document : inventory) {
            Double distance1 = (Double) document.get("distance");
            Long uid1 = (Long) document.get("uid");
            Integer gender = (Integer) document.get("gender");
            String address = (String) document.get("address");
            List<Double> loc = (List<Double>) document.get("loc");
            NearbyUser nearbyUser = new NearbyUser();
            nearbyUser.setUid(uid1);
            nearbyUser.setGender(gender);
            nearbyUser.setAddress(address);
            nearbyUser.setDistance( (int) (distance1/1000) + "m");
            nearbyUser.setLon(loc.get(0));
            nearbyUser.setLat(loc.get(1));

            ret.add(nearbyUser);
        }

        return ret;
    }
}
